package com.joven.shelltest.utils;

import sun.misc.BASE64Encoder;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;

/**
 * 斜边铺满水印
 * @Author wzj
 * @Date 2023-08-16 11:34
 **/
public class WaterMarkAddUtils {
    public static void main(String[] args) throws IOException {
        long start = System.currentTimeMillis();
        waterMarkAdd("D:/image/test.jpg","D:/image/t_test.jpg","18757809377_汪鸿毅");
        System.out.println(System.currentTimeMillis()-start);
    }


    public static void waterMarkAdd(String sourceFile,String targetFile,String watermarkText)
            throws IOException {
        File srcImgFile = new File(sourceFile);
        Image srcImg = ImageIO.read(srcImgFile);
        int srcImgWidth = srcImg.getWidth(null);
        int srcImgHeight = srcImg.getHeight(null);
        //以图片宽高中短的一边为基准长度，控制水印的大小
        int baseLength = (srcImgHeight + srcImgWidth) / 2;
        BufferedImage bufImg = new BufferedImage(srcImgWidth, srcImgHeight, BufferedImage.TYPE_INT_RGB);
        //创建画笔
        Graphics2D g = bufImg.createGraphics();
        //srcImg 为上面获取到的原始图片的图片对象
        g.drawImage(srcImg, 0, 0, srcImgWidth, srcImgHeight, null);
        //设置字体大小，大小根据图片尺寸变化，最小为30+文字长度
        int fontSize = Math.max(baseLength / 20, 30 + watermarkText.length());
        int textLength = g.getFontMetrics(g.getFont()).charsWidth(watermarkText.toCharArray(), 0, watermarkText.length());
        //自适应文字大小
        fontSize = (int) (fontSize - textLength * 0.2);
        int fontLength = fontSize * (watermarkText.length() + 2);
        //水印图片的宽
        int watermarkImageWidth = (int) (fontLength * 0.7);
        //水印图片的高
        int watermarkImageHeight = fontLength / 2;
        BufferedImage watermarkImage = new BufferedImage(watermarkImageWidth, watermarkImageHeight, BufferedImage.TYPE_INT_RGB);
        Graphics2D rotatedG2d = watermarkImage.createGraphics();
        //设置背景为透明
        watermarkImage = rotatedG2d.getDeviceConfiguration().createCompatibleImage(watermarkImageWidth, watermarkImageHeight, Transparency.TRANSLUCENT);
        rotatedG2d.dispose();
        //开始绘制水印文字
        rotatedG2d = watermarkImage.createGraphics();
        rotatedG2d.setFont(new Font("微软雅黑", Font.PLAIN, fontSize));
        //文字自适应图片颜色
        rotatedG2d.setColor(getMarkColor(bufImg, srcImgWidth, srcImgHeight));
        double halfWidth = watermarkImageWidth / 2.0;
        //水印文字逆时针旋转30°
        rotatedG2d.rotate(Math.toRadians(-30), halfWidth, watermarkImageHeight / 2.0);
        rotatedG2d.drawString(watermarkText, (int) (fontSize * 0.1), (int) (watermarkImageHeight / 1.75));
        rotatedG2d.dispose();
        //第一个水印的起始位置
        int startX = 0;
        int startY = (int) (-halfWidth);
        //循环添加水印
        for (int posX = startX; posX <= srcImgWidth; posX += watermarkImageWidth) {
            for (int posY = startY; posY <= srcImgHeight; posY += watermarkImageHeight) {
                //将绘制的水印文字图片画到原图片
                g.drawImage(watermarkImage, posX, posY, null);
            }
        }
        g.dispose();
        // 输出图片
        FileOutputStream outImgStream = new FileOutputStream(targetFile);
        //这里转出的格式要与原来的相同，不然图片文件会变得异常大
        String fileExtName = sourceFile.substring(sourceFile.lastIndexOf(".") + 1);
        ImageIO.write(bufImg, fileExtName, outImgStream);
        System.out.println("添加水印完成");
        outImgStream.flush();
        outImgStream.close();
    }

    public static Color getMarkColor(BufferedImage bi, int w, int h) {
        long sumR = 0;
        long sumG = 0;
        long sumB = 0;
        for (int x = 0; x < w; x++) {
            for (int y = 0; y < h; y++) {
                Color pixel = new Color(bi.getRGB(x, y));
                sumR += pixel.getRed();
                sumG += pixel.getGreen();
                sumB += pixel.getBlue();
            }
        }
        int num = w * h;
        int markColor = (int) (sumR / num + sumG / num + sumB / num) / 3;
        int halfRgb = 128;
        if (markColor < halfRgb) {
            markColor = markColor - 50 < 0 ? markColor + 50 : markColor - 50;
        } else {
            markColor = markColor + 50 > 255 ? markColor - 50 : markColor + 50;
        }
        return new Color(markColor, markColor, markColor, 100);
    }

    public static String waterMarkAdd2(InputStream inputStream, String watermarkText)
            throws IOException {
//        File srcImgFile = new File(sourceFile);
        Image srcImg = ImageIO.read(inputStream);
        int srcImgWidth = srcImg.getWidth(null);
        int srcImgHeight = srcImg.getHeight(null);
        //以图片宽高中短的一边为基准长度，控制水印的大小
        int baseLength = (srcImgHeight + srcImgWidth) / 2;
        BufferedImage bufImg = new BufferedImage(srcImgWidth, srcImgHeight, BufferedImage.TYPE_INT_RGB);
        //创建画笔
        Graphics2D g = bufImg.createGraphics();
        //srcImg 为上面获取到的原始图片的图片对象
        g.drawImage(srcImg, 0, 0, srcImgWidth, srcImgHeight, null);
        //设置字体大小，大小根据图片尺寸变化，最小为20+文字长度
        int fontSize = Math.max(baseLength / 30, 10 + watermarkText.length());
        int textLength = g.getFontMetrics(g.getFont()).charsWidth(watermarkText.toCharArray(), 0, watermarkText.length());
        //自适应文字大小
        fontSize = (int) (fontSize - textLength * 0.2);
        int fontLength = fontSize * (watermarkText.length() + 2);
        //水印图片的宽
        int watermarkImageWidth = (int) (fontLength * 0.8);
        //水印图片的高
        int watermarkImageHeight = fontLength / 2;
        BufferedImage watermarkImage = new BufferedImage(watermarkImageWidth, watermarkImageHeight, BufferedImage.TYPE_INT_RGB);
        Graphics2D rotatedG2d = watermarkImage.createGraphics();
        //设置背景为透明
        watermarkImage = rotatedG2d.getDeviceConfiguration().createCompatibleImage(watermarkImageWidth, watermarkImageHeight, Transparency.TRANSLUCENT);
        rotatedG2d.dispose();
        //开始绘制水印文字
        rotatedG2d = watermarkImage.createGraphics();
        rotatedG2d.setFont(new Font("微软雅黑", Font.PLAIN, fontSize));
        //文字自适应图片颜色
        rotatedG2d.setColor(getMarkColor(bufImg, srcImgWidth, srcImgHeight));
        double halfWidth = watermarkImageWidth / 2.0;
        //水印文字逆时针旋转30°
        rotatedG2d.rotate(Math.toRadians(-30), halfWidth, watermarkImageHeight / 2.0);
        rotatedG2d.drawString(watermarkText, (int) (fontSize * 0.1), (int) (watermarkImageHeight / 1.75));
        rotatedG2d.dispose();
        //第一个水印的起始位置
        int startX = 0;
        int startY = (int) (-halfWidth);
        //循环添加水印
        for (int posX = startX; posX <= srcImgWidth; posX += watermarkImageWidth) {
            for (int posY = startY; posY <= srcImgHeight; posY += watermarkImageHeight) {
                //将绘制的水印文字图片画到原图片
                g.drawImage(watermarkImage, posX, posY, null);
            }
        }
        g.dispose();


        ByteArrayOutputStream baosOut = new ByteArrayOutputStream();
        try {
            ImageIO.write(bufImg, "jpg", baosOut);
        } catch (IOException e) {
            e.printStackTrace();
        }
        //转换成字节
        byte[] bytes = baosOut.toByteArray();
        BASE64Encoder encoder = new BASE64Encoder();
        //转换成base64串
        String pngBase64 = encoder.encodeBuffer(bytes).trim();
        //删除 \r\n
        pngBase64 = pngBase64.replaceAll("\n", "").replaceAll("\r", "");
        return pngBase64;
    }
}
